package service

import (
	"context"
	"github.com/gin-gonic/gin"
	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/bson/primitive"
	"go.mongodb.org/mongo-driver/mongo"
	"time"
	"user-center/src/common"
	"user-center/src/constant"
	"user-center/src/db"
	"user-center/src/model"
	"user-center/src/model/VO"
	"user-center/src/model/request"
	"user-center/src/model/response"
)

func GroupCreate(ctx *gin.Context, teamId int64, name string) *response.BaseResponse {
	res := &response.BaseResponse{}
	chatGroup := model.GroupChat{
		TeamId: teamId,
		Name:   name,
	}

	// 检查MySQL中的team_Id是否存在
	var team model.Team
	if err := db.GetMySQL().Where("Id  = ? and isDelete = 0", chatGroup.TeamId).First(&team).Error; err != nil {
		res.ResponseWithError(common.NO_INFO, "InvalId team_Id")
		return res
	}

	chatGroup.Id = primitive.NewObjectID()
	chatGroup.CreatedAt = time.Now()
	chatGroup.Avatar = constant.GroupAvatar

	_, err := db.GetMongo().ChatGroupsCollection.InsertOne(context.Background(), chatGroup)
	if err != nil {
		res.ResponseWithError(common.SYSTEM_ERROR, "创建群聊错误")
		return res
	}

	return GroupChatAdd(ctx, &request.GroupMessageRequest{GroupChatId: chatGroup.Id.Hex(), SenderId: GetUserCurrentInfo(ctx).Id, Message: "我创建了新队伍"})
}

func GroupChatAdd(ctx *gin.Context, msgReq *request.GroupMessageRequest) *response.BaseResponse {
	res := &response.BaseResponse{}
	user := GetUserCurrentInfo(ctx)
	if user == nil {
		res.ResponseWithError(common.NOT_LOGIN, "未登录")
	}
	if msgReq.SenderId <= 0 {
		msgReq.SenderId = user.Id
	}
	objectId, err := primitive.ObjectIDFromHex(msgReq.GroupChatId)
	if err != nil {
		res.ResponseWithError(common.PARAMS_ERROR, "InvalId chat group Id")
		return res
	}
	// 1 todo 检查groupId

	// 检查MySQL中的sender_Id是否存在
	if err = db.GetMySQL().Where("id = ?  and isDelete = 0", msgReq.SenderId).First(user).Error; err != nil {
		res.ResponseWithError(common.PARAMS_ERROR, "InvalId senderId")
		return res
	}

	message := &model.GroupMessage{
		Id:          primitive.NewObjectID(),
		GroupChatId: objectId,
		SentAt:      time.Now(),
		SenderId:    msgReq.SenderId,
		Message:     msgReq.Message,
	}
	_, err = db.GetMongo().MessagesCollection.InsertOne(context.Background(), message)
	if err != nil {
		res.ResponseWithError(common.PARAMS_ERROR, err.Error())
		return res
	}

	return res
}

func ListGroups(ctx *gin.Context, pageNum, pageSize int, user *model.User) *response.BaseResponse {
	res := &response.BaseResponse{}
	if user == nil {
		res.ResponseWithError(common.NOT_LOGIN, "未登录")
		return res
	}
	//todo 添加
	if pageNum <= 0 {
		pageNum = 1
	}
	if pageSize <= 0 {
		pageSize = 20
	}

	var userTeam []model.UserTeam

	if err := db.GetMySQL().Select("teamId").Where("userId = ? and isDelete = 0  ", user.Id).Find(&userTeam).Error; err != nil {
		res.ResponseWithError(common.SYSTEM_ERROR, "数据库查询失败")
		return res
	}
	var teamIds []int
	for _, i := range userTeam {
		teamIds = append(teamIds, int(i.TeamId))
	}
	filter := bson.M{"teamId": bson.M{"$in": teamIds}}
	cursor, err := db.GetMongo().ChatGroupsCollection.Find(ctx, filter)
	if err != nil {
		res.ResponseWithError(common.SYSTEM_ERROR, "群聊队伍查询失败")
		return res
	}
	defer cursor.Close(ctx)

	var chatGroups []model.GroupChat
	if err := cursor.All(ctx, &chatGroups); err != nil {
		res.ResponseWithError(common.SYSTEM_ERROR, "群聊队伍查询失败")
		return res
	}

	chatGroupIds := make([]primitive.ObjectID, len(chatGroups))
	for i, chatGroup := range chatGroups {
		chatGroupIds[i] = chatGroup.Id
	}

	pipeline := mongo.Pipeline{
		bson.D{{"$match", bson.D{{"GroupChatId", bson.D{{"$in", chatGroupIds}}}}}},
		bson.D{{"$sort", bson.D{{"sentAt", -1}}}},
		bson.D{{"$group", bson.D{
			{"_id", "$GroupChatId"},
			{"latest_message", bson.D{{"$first", "$$ROOT"}}},
		}}},
	}

	cursor, err = db.GetMongo().MessagesCollection.Aggregate(ctx, pipeline)
	if err != nil {
		res.ResponseWithError(common.SYSTEM_ERROR, "消息数据查询失败")
		return res
	}
	defer cursor.Close(ctx)

	var latestMessages []model.GroupMessage
	for cursor.Next(ctx) {
		var result struct {
			Id            primitive.ObjectID `bson:"_Id"`
			LatestMessage model.GroupMessage `bson:"latest_message"`
		}
		if err = cursor.Decode(&result); err != nil {
			res.ResponseWithError(common.SYSTEM_ERROR, "消息数据查询失败")
			return res
		}
		latestMessages = append(latestMessages, result.LatestMessage)
	}
	var resData []VO.GroupChatVO
	for _, i := range latestMessages {
		for _, j := range chatGroups {
			if i.GroupChatId == j.Id {
				data := VO.GroupChatVO{
					SenderUserId:    i.SenderId,
					GroupChatId:     i.GroupChatId.Hex(),
					GroupChatAvatar: j.Avatar,
					GroupChatName:   j.Name,
					Message:         i.Message,
					SentAt:          i.SentAt,
				}
				resData = append(resData, data)
			}
		}
	}
	res.ResponseWithData(resData)
	return res
}

func ListHistoryByGroup(ctx *gin.Context, GroupChatId string) *response.BaseResponse {
	res := &response.BaseResponse{}
	objectId, err := primitive.ObjectIDFromHex(GroupChatId)
	if err != nil {
		res.ResponseWithError(common.PARAMS_ERROR, "InvalId chat group Id")
		return res
	}

	var messages []model.GroupMessage
	cursor, err := db.GetMongo().MessagesCollection.Find(context.Background(), bson.M{"GroupChatId": objectId})
	if err != nil {
		res.ResponseWithError(common.NULL_ERROR, err.Error())
		return res
	}
	defer cursor.Close(context.Background())

	for cursor.Next(context.Background()) {
		var message model.GroupMessage
		if err := cursor.Decode(&message); err != nil {
			res.ResponseWithError(common.NULL_ERROR, err.Error())
			return res
		}
		messages = append(messages, message)
	}
	res.ResponseWithData(messages)
	return res
}

func ListMemberByGroup(ctx *gin.Context, GroupChatId string) *response.BaseResponse {
	res := &response.BaseResponse{}
	objectId, err := primitive.ObjectIDFromHex(GroupChatId)
	if err != nil {
		res.ResponseWithError(common.PARAMS_ERROR, "InvalId chat group Id")
		return res
	}

	// 获取队伍Id
	var group model.GroupChat
	err = db.GetMongo().ChatGroupsCollection.FindOne(context.Background(), bson.M{"_id": objectId}).Decode(&group)
	if err != nil {
		res.ResponseWithError(common.NO_INFO, err.Error())
		return res
	}

	var userTeam []model.UserTeam
	if err = db.GetMySQL().Where("teamId = ? and isDelete = 0", group.TeamId).Find(&userTeam).Error; err != nil {
		res.ResponseWithError(common.NULL_ERROR, err.Error())
		return res
	}

	var userId []int64
	for _, i := range userTeam {
		userId = append(userId, i.UserId)
	}

	var userInfo []model.User
	if err = db.GetMySQL().Where("id in (?) and isDelete = 0  ", userId).Find(&userInfo).Error; err != nil {
		res.ResponseWithError(common.NULL_ERROR, err.Error())
		return res
	}
	res.ResponseWithData(userInfo)
	return res
}
